package org.etom.impl.connector.util;

import java.io.File;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.HttpVersion;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.etom.connector.service.ConnectorException;

/**
 * An utility class which is responsible for the upload to Moodle server.
 */
public class Uploader {

  private static final String UPLOAD_FILE_NAME = "newfile"; //magic constant, it is used in moodle upload manager

  /**
   * The method uploads file to Moodle server
   * 
   * @param serverUrl - the server URL
   * @param file - the file which will be uploaded
   * @param requestProps - the upload request properties
   * 
   * @throws ConnectorException - if an error is occurred in the upload operation
   */
  public static void upload(String serverUrl, File file, Map<String, String> requestProps) throws ConnectorException {

    PostMethod filePost = new PostMethod(serverUrl);
    if (null != requestProps) {
      HttpMethodParams hpptParams = filePost.getParams();
      hpptParams.setVersion(HttpVersion.HTTP_1_1);
      //we cares about the cookies, the apache lib should not touch it
      hpptParams.setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
      Iterator<String> keysIter = requestProps.keySet().iterator();
      String currentKey;
      filePost.setDoAuthentication(false);
      filePost.setFollowRedirects(false);
      while(keysIter.hasNext()) {
        currentKey = keysIter.next();
        filePost.setRequestHeader(currentKey, requestProps.get(currentKey));
      }
    }
    try {
      Part[] parts = { new FilePart(UPLOAD_FILE_NAME, file) };
      filePost.setRequestEntity(
          new MultipartRequestEntity(parts, filePost.getParams()));
      HttpClient client = new HttpClient();
      client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
      int status = client.executeMethod(null, filePost, null);
      if (status != HttpStatus.SC_OK) {
        throw new ConnectorException(
            "The status of the upload is not expected! Status: " + HttpStatus.getStatusText(status),
            ConnectorException.FAULT_RESPONSE);
      }
    } catch (ConnectorException ce) {
      throw ce;
    } catch (Exception ex) {
      throw new ConnectorException("An exception is occured in upload operation!",
          ConnectorException.CONNECTION_ERROR, ex);
    } finally {
      filePost.releaseConnection();
    }
  }

}
